/**
 @file ctc_port_cli.c

 @date 2020-06-23

 @version v1.0

---file comments----
*/

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_cli.h"
#include "ctc_cli_common.h"
#include "api/include/ctcs_api.h"
#include "ctc_common.h"
#include "ctc_asw_common.h"
#define CTC_CLI_GPHYPORT_ID_DESC  "type(4bit)|reserve(10bit)|lport_ext(3bit) | gchip(7bit, 0x1F for linkagg) | lport/linkagg_id (8bit)"
#define CTC_CLI_LCHIP_ID_STR      "Local chip id"
#define CTC_CLI_LCHIP_ID_VALUE    "<0~chip_num-1> ,the lchip_num can be changed by ctc_chip_init() when you initialize SDK ,lchip_num default is 1."

CTC_CLI(ctc_cli_asw_port_set_stag_tpid_index,
        ctc_cli_asw_port_set_stag_tpid_index_cmd,
        "port GPHYPORT_ID stag-tpid-index direction (ingress|egress|both) INDEX",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Stag TPID index point to stag TPID value",
        "Direction",
        "Ingress",
        "Egress",
        "Both direction",
        "<0-3>")
{
    int32 ret = 0;
    uint16 gport = 0;
    uint8 index = 0;
    ctc_direction_t dir = CTC_BOTH_DIRECTION;

    CTC_CLI_GET_UINT16("gport", gport, argv[0]);
    CTC_CLI_GET_UINT8("stpid index", index, argv[2]);

    if (CLI_CLI_STR_EQUAL("ingress", 1))
    {
        dir = CTC_INGRESS;
    }
    else if (CLI_CLI_STR_EQUAL("egress", 1))
    {
        dir = CTC_EGRESS;
    }
    ret = ctcs_port_set_stag_tpid_index(g_api_lchip, gport, dir, index);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_port_isolation,
        ctc_cli_asw_port_set_port_isolation_cmd,
        "port isolation (source VALUE) dest {pbmp0 PORT_BITMAP_0 | pbmp1 PORT_BITMAP_1 | pbmp2 PORT_BITMAP_2 | pbmp3 PORT_BITMAP_3 | \
        pbmp4 PORT_BITMAP_4 | pbmp5 PORT_BITMAP_5 | pbmp6 PORT_BITMAP_6 | pbmp7 PORT_BITMAP_7 | pbmp8 PORT_BITMAP_8 | pbmp9 PORT_BITMAP_9 } \
           (packet-type {ucast-flooding | mcast-flooding |bcast-flooding | all}|)",
        CTC_CLI_PORT_M_STR,
        "Port isolation",
        "Source ",
        "Value is port",
        "Destination",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Isolate forward packet type",
        "ucast packet will be isolated",
        "mcast packet will be isolated",
        "Broadcast packet will be isolated",
        "All packet will be isolated")
{
    int32 ret = 0;
    uint8 index = 0xFF;
    ctc_port_isolation_t port_isolation;

    sal_memset(&port_isolation, 0, sizeof(port_isolation));

    index = CTC_CLI_GET_ARGC_INDEX("source");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT16("source", port_isolation.gport, argv[index+1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX("pbmp0");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("port bitmap 0", port_isolation.pbm[0], argv[index + 1]);
    }

    if (MAX_PORT_NUM_PER_CHIP > 256)
    {
        index = CTC_CLI_GET_ARGC_INDEX("pbmp8");
        if (index != 0xFF)
        {
            CTC_CLI_GET_UINT32("port bitmap 8", port_isolation.pbm[8], argv[index + 1]);
        }
        index = CTC_CLI_GET_ARGC_INDEX("pbmp9");
        if (index != 0xFF)
        {
            CTC_CLI_GET_UINT32("port bitmap 9", port_isolation.pbm[9], argv[index + 1]);
        }
    }


    index = CTC_CLI_GET_ARGC_INDEX("ucast-flooding");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |=  CTC_PORT_ISOLATION_UNKNOW_UCAST;
    }

    index = CTC_CLI_GET_ARGC_INDEX("mcast-flooding");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |=  CTC_PORT_ISOLATION_UNKNOW_MCAST;
    }

    index = CTC_CLI_GET_ARGC_INDEX("bcast-flooding");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |= CTC_PORT_ISOLATION_BCAST;
    }
    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |= CTC_PORT_ISOLATION_ALL;
    }

    ret = ctcs_port_set_isolation(g_api_lchip, &port_isolation);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}


CTC_CLI(ctc_cli_asw_port_show_port_isolation,
        ctc_cli_asw_port_show_port_isolation_cmd,
        "show port isolation (source VALUE) (packet-type {ucast-flooding | mcast-flooding | known-ucast-forwarding | known-mcast-forwarding | bcast-flooding}|)",
        CTC_CLI_SHOW_STR,
        CTC_CLI_PORT_M_STR,
        "Port isolation",
        "Source ",
        "Value",
       "Isolate forward packet type",
        "ucast packet will be isolated",
        "mcast packet will be isolated",
        "Broadcast packet will be isolated",
        "All packet will be isolated",
        "if set, dest is linkagg bitmap, used for MLAG port isolation")
{
    int32 ret = 0;
    uint8 index = 0xFF;

    ctc_port_isolation_t port_isolation;

    sal_memset(&port_isolation, 0, sizeof(port_isolation));

    index = CTC_CLI_GET_ARGC_INDEX("source");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT16("source", port_isolation.gport, argv[index+1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX("ucast-flooding");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |=  CTC_PORT_ISOLATION_KNOW_UCAST;
    }

    index = CTC_CLI_GET_ARGC_INDEX("mcast-flooding");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |=  CTC_PORT_ISOLATION_KNOW_MCAST;
    }

    index = CTC_CLI_GET_ARGC_INDEX("bcast-flooding");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |= CTC_PORT_ISOLATION_BCAST;
    }

    index = CTC_CLI_GET_ARGC_INDEX("all-flooding");
    if (index != 0xFF)
    {
        port_isolation.isolation_pkt_type |= CTC_PORT_ISOLATION_ALL;
    }

    ret = ctcs_port_get_isolation(g_api_lchip, &port_isolation);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }


    ctc_cli_out("show port isolation egress: \n");
    ctc_cli_out("=====================================\n");
    ctc_cli_out("pbm0            : 0x%x\n", port_isolation.pbm[0]);

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_port_set_learning,
        ctc_cli_asw_port_set_learning_cmd,
        "port GPHYPORT_ID learning (enable |disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Mac learning",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint16 gport = 0;
    bool learning_en = FALSE;

    CTC_CLI_GET_UINT16("gport", gport, argv[0]);


    if (0 == sal_memcmp("en", argv[1], 2))
    {
        learning_en = TRUE;
    }
    ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_LEARNING_EN, learning_en);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_newsa_drop_list,
        ctc_cli_asw_port_set_newsa_drop_cmd,
        "port GPHYPORT_ID newsa-drop (enable |disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "New sa drop and not to learn",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint16 gport = 0;
    bool value = FALSE;

    CTC_CLI_GET_UINT16("gport", gport, argv[0]);


    if (0 == sal_memcmp("en", argv[1], 2))
    {
        value = TRUE;
    }
    ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_NEW_SA_DROP, value);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}
CTC_CLI(ctc_cli_asw_port_show_port_info,
        ctc_cli_asw_port_show_port_info_cmd,
        "show port GPHYPORT_ID (all | bridge | default-vlan\
        | learning-enable | newsa-drop | vlan-ctl | ingress-vlan-filtering | egress-vlan-filtering | \
        vlan-domain | ingress-stpid-index | egress-stpid-index | \
        mac-en | max-frame-size | \
        port-blocking (ucast-flooding|mcast-flooding|bcast-flooding ) | \
        ((scl-key-type scl-id SCL_ID | vlan-range (block-id BLOCK_ID | ))))",
        CTC_CLI_SHOW_STR,
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Show all property",
        "L2 bridge",
        "Default vlan id",
        "Mac learning enable",
        "New sa drop and not to learn",
        "Vlan tag control",
        "Ingress vlan filtering",
        "Egress vlan filtering",
        "Vlan domain when STPID is the same as CTPID",
        "Ingress stag tpid index",
        "Egress stag tpid index",
        "Mac enable",
        "Max frame size",
        "Port based blocking",
        "Unknown ucast flooding to this port",
        "Unknown mcast flooding to this port",
        "Broadcast flooding to this port",
        "SCL key type",
        "SCL id",
        "Scl lookup ID Value",
        "Vlan Range",
        "Block id",
        "Value")
{
    int32 ret = CLI_SUCCESS;
    uint32 gport;
    uint8 val_8 = 0;
    uint32 val_32 = 0;
    char* str = NULL;
    uint8 index = 0xFF;
    uint8 show_all = 0;
    uint32 value = 0;
    bool enable = FALSE;
    ctc_port_scl_property_t port_scl_property;
    ctc_vlan_range_info_t vrange_info;
    ctc_port_restriction_t port_restrict;
    uint8 block_id = 0;

    sal_memset(&port_scl_property, 0, sizeof(ctc_port_scl_property_t));
    sal_memset(&vrange_info, 0, sizeof(ctc_vlan_range_info_t));
    sal_memset(&port_restrict, 0, sizeof(ctc_port_restriction_t));
    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (index != 0xFF)
    {
        show_all = 1;
    }

    CTC_CLI_GET_UINT32("gport", gport, argv[0]);

    ctc_cli_out("%-45s:  0x%04x\n", "Show GPort", gport);
    ctc_cli_out("--------------------------------------------------------\n");

    index = CTC_CLI_GET_ARGC_INDEX("default-vlan");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_VLAN, &val_32);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Default vlan", val_32);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("learning-enable");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_LEARNING_EN, &val_32);
        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Learning enable", val_32);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("newsa-drop");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_NEW_SA_DROP, &val_32);
        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "newsa-drop", val_32);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("vlan-ctl");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_VLAN_CTL, (ctc_vlantag_ctl_t*)&val_32);

        if (ret >= 0)
        {
            switch (val_32)
            {
                case 0:
                    str = "allow-all";
                    break;
                case 1:
                    str = "drop-all-untagged";
                    break;
                case 2:
                    str = "drop-all-tagged";
                    break;
                case 3:
                    str = "drop-all";
                    break;
                default:
                    break;
            }

            ctc_cli_out("%-45s:  %s\n", "Vlan control", str);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("ingress-vlan-filtering");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_direction_property(g_api_lchip, gport, CTC_PORT_DIR_PROP_VLAN_FILTER_EN, CTC_INGRESS, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Ingress vlan filtering", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("egress-vlan-filtering");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_direction_property(g_api_lchip, gport, CTC_PORT_DIR_PROP_VLAN_FILTER_EN, CTC_EGRESS, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Egress vlan filtering", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("ingress-stpid-index");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_stag_tpid_index(g_api_lchip, gport, CTC_INGRESS, &val_8);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Ingress stag tpid index", val_8);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("egress-stpid-index");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_stag_tpid_index(g_api_lchip, gport, CTC_EGRESS, &val_8);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Egress stag tpid index", val_8);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("mac-en");
    if ((index != 0xFF) || show_all)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_MAC_EN, &val_32);
        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "MAC enable", val_32);
        }
    }
    if ((ret < 0) && (!show_all))
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    index = CTC_CLI_GET_ARGC_INDEX("scl-key-type");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("scl id", port_scl_property.scl_id, argv[index + 2], 0, CTC_MAX_UINT8_VALUE);
        port_scl_property.direction = CTC_INGRESS;
        ret = ctcs_port_get_scl_property(g_api_lchip, gport, &port_scl_property);
        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
            return CLI_ERROR;
        }
        ctc_cli_out("%-45s:  %u\n", "Scl hash key type", port_scl_property.hash_type);
        ctc_cli_out("%-45s:  %u\n", "Scl tcam key type", port_scl_property.tcam_type);
        ctc_cli_out("%-45s:  %u\n", "Hash vlan range en", !port_scl_property.hash_vlan_range_dis);
    }

    index = CTC_CLI_GET_ARGC_INDEX("vlan-range");
    if (0xFF != index)
    {
        index = CTC_CLI_GET_ARGC_INDEX("block-id");
        if (0xFF != index)
        {
            CTC_CLI_GET_UINT8("block id", block_id, argv[index + 1]);
        }

        ret = ctcs_port_get_vlan_range(g_api_lchip, gport, &vrange_info, &enable);

        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
            return CLI_ERROR;
        }

        if (!enable)
        {
            ctc_cli_out("%-45s:  %s\n", "Vlan range", "disable");
        }
        else
        {
            ctc_cli_out("%-45s:  %s\n", "Vlan range", "enable");
            ctc_cli_out("%-45s:  %u\n", "Vlan range group", vrange_info.vrange_grpid);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("vlan-domain");
    if ((index != 0xFF) || show_all)
    {

        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_VLAN_DOMAIN, (ctc_port_vlan_domain_type_t*)&value);

        if (0 == value)
        {
            str = "svlan";
        }
        else
        {
            str = "cvlan";
        }

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %s\n", "Vlan domain", str);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("port-blocking");
    if (index != 0xFF)
    {
        port_restrict.mode = CTC_PORT_RESTRICTION_PORT_BLOCKING;
        ret = ctcs_port_get_restriction(g_api_lchip, gport, &port_restrict);
        index = CTC_CLI_GET_ARGC_INDEX("ucast-flooding");
        if (index != 0xFF)
        {
            value = (port_restrict.type & CTC_PORT_BLOCKING_UNKNOW_UCAST) ? 1 : 0;
            ctc_cli_out("%-45s:  %u\n", "Unknown ucast flood block", value);
        }

        index = CTC_CLI_GET_ARGC_INDEX("mcast-flooding");
        if (index != 0xFF)
        {
            value = (port_restrict.type & CTC_PORT_BLOCKING_UNKNOW_MCAST) ? 1 : 0;
            ctc_cli_out("%-45s:  %u\n", "Unknown mcast flood block", value);
        }

        index = CTC_CLI_GET_ARGC_INDEX("bcast-flooding");
        if (index != 0xFF)
        {
            value = (port_restrict.type & CTC_PORT_BLOCKING_BCAST) ? 1 : 0;
            ctc_cli_out("%-45s:  %u\n", "Bcast flood block", value);
        }
    }
    
    if (show_all)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_STAG_COS, &value);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Replace-stag-cos", value);
        }

        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_DSCP_EN, &value);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Replace-dscp", value);
        }

        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_PCP, &value);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Default-pcp", value);
        }
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_DEI, &value);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Default-dei", value);
        }


        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_QOS_POLICY, &value);


        switch (value)
        {
            case CTC_QOS_TRUST_PORT:
                str = "port";
                break;
            case CTC_QOS_TRUST_STAG_COS:
                str = "stag-cos";
                break;
            case CTC_QOS_TRUST_DSCP:
                str = "dscp";
                break;
            default:
                str = "unexpect!!!!!";
                break;
        }

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %s\n", "Qos-trust", str);
        }

        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_CHK_CRC_EN, &value);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Check CRC", value);
        }

        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_STRIP_CRC_EN, &value);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Strip CRC", value);
        }

        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_APPEND_CRC_EN, &value);

        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Append CRC", value);
        }
    }
    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_port_set_dir_property,
        ctc_cli_asw_port_set_dir_property_cmd,
        "port GPHYPORT_ID dir-property ( qos-domain | policer-valid ) direction (ingress|egress|both) value VALUE ",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Port property with direction",
        "Port qos domain",
        "Port policer valid",
        "Direcion",
        "Ingress",
        "Egress",
        "Both direction",
        "Property value",
        "Value")
{
    uint8 index = 0;
    int32 ret = 0;
    uint16 gport = 0;
    uint32 value = 0;
    ctc_direction_t dir = CTC_INGRESS;
    uint32  prop = 0;
    CTC_CLI_GET_UINT16("gport", gport, argv[0]);
    CTC_CLI_GET_UINT32("value", value, argv[argc - 1]);

    index = CTC_CLI_GET_ARGC_INDEX("ingress");
    if (INDEX_VALID(index))
    {
        dir = CTC_INGRESS;
    }

    index = CTC_CLI_GET_ARGC_INDEX("egress");
    if (INDEX_VALID(index))
    {
        dir = CTC_EGRESS;
    }

    index = CTC_CLI_GET_ARGC_INDEX("both");
    if (INDEX_VALID(index))
    {
        dir = CTC_BOTH_DIRECTION;
    }

    if (CLI_CLI_STR_EQUAL("qos-domain", 1))
    {
        prop = CTC_PORT_DIR_PROP_QOS_DOMAIN;
    }
    else if (CLI_CLI_STR_EQUAL("policer-valid", 1))
    {
        prop = CTC_PORT_DIR_PROP_PORT_POLICER_VALID;
    }
    ret = ctcs_port_set_direction_property(g_api_lchip, gport, prop, dir, value);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

/*  "Set low 8 bits for da port MAC",
    "Set da port MAC high 40 bits register select",
    "Set low 8 bits for sa port MAC",
    "Set sa port MAC high 40 bits register select" */

CTC_CLI(ctc_cli_asw_port_set_property,
        ctc_cli_asw_port_set_property_cmd,
        "port GPHYPORT_ID property (((replace-stag-cos | replace-ctag-cos | replace-dscp | default-pcp | default-dei | default-dscp|replace-pcp-dei| \
        check-crc|strip-crc|append-crc|max-frame-size| half-duplex |priority-tag| station-move-action | dscp-mode| auto-neg |qos-wrr|preamble |ipg-index|unidirection|\
        link-intr|phy-init|phy-en| phy-duplex | phy-medium |phy-loopback | phy-auto-neg)value VALUE)|(qos-trust (port | stag-cos | dscp ))|\
        (auto-neg-mode (1000base-X| sgmii-slaver | sgmii-master)))",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Property",
        "The STAG COS field is replaced by the classified COS result",
        "The CTAG COS field is replaced by the classified COS result",
        "The Dscp field is replace by qos mapping",
        "Default cos of vlan tag",
        "Default dei of vlan tag",
        "Default dscp",
        "Replace pcp dei",
        "Check CRC",
        "Strip CRC",
        "Append CRC",
        "Max frame size",
        "Half duplex",
        "Priroty tag on port recevice or drop",
        "Station move action, 0:fwd, 1:discard, 2:discard and to cpu",
        "Dscp select mode, refer to ctc_dscp_select_mode_t",
        "Auto neg enable",
        "Qos WRR mode",
        "Port preamble",
        "Ipg index",
        "Unidirection",
        "Pcs link change interrupt enable",
        "Phy init",
        "Phy enable",
        "Phy duplex",
        "Phy medium",
        "Phy loopback",
        "Phy auto neg",
        "Property value",
        "Value",
        "Qos trust policy",
        "Classifies ingress packets with the port default CoS value",
        "Classifies ingress packets with the packet Stag CoS values",
        "Classifies ingress packets with the packet DSCP values",
        "Auto neg mode",
        "1000Base-X",
        "Sgmii-slaver",
        "Sgmii-master")
{
    int32 ret = 0;
    uint16 gport;
    uint32 value = 0;
    uint8 index = 0xFF;
    CTC_CLI_GET_UINT16("gport", gport, argv[0]);
    index = CTC_CLI_GET_ARGC_INDEX("value");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("Property_value", value, argv[index + 1]);
    }
    if (CLI_CLI_STR_EQUAL("replace-stag-cos", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_STAG_COS, value);
    }
    else if (CLI_CLI_STR_EQUAL("replace-ctag-cos", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_CTAG_COS, value);
    }
    else if (CLI_CLI_STR_EQUAL("replace-dscp", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_DSCP_EN, value);
    }

    else if (CLI_CLI_STR_EQUAL("default-pcp", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_PCP, value);
    }
    else if (CLI_CLI_STR_EQUAL("default-dei", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_DEI, value);
    }

    else if (CLI_CLI_STR_EQUAL("qos-trust", 1))
    {
        if (CLI_CLI_STR_EQUAL("port", 2))
        {
            value = CTC_QOS_TRUST_PORT;
        }
        else if (CLI_CLI_STR_EQUAL("stag-cos", 2))
        {
            value = CTC_QOS_TRUST_STAG_COS;
        }
        else if (CLI_CLI_STR_EQUAL("dscp", 2))
        {
            value = CTC_QOS_TRUST_DSCP;
        }
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_QOS_POLICY, value);
    }
    else if (CLI_CLI_STR_EQUAL("default-dscp", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_DSCP, value);
    }
    else if (CLI_CLI_STR_EQUAL("replace-pcp-dei", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_PCP_DEI, value);
    }
    else if (CLI_CLI_STR_EQUAL("check-crc", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_CHK_CRC_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("strip-crc", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_STRIP_CRC_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("append-crc", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_APPEND_CRC_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("max-frame-size", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_MAX_FRAME_SIZE, value);
    }
    else if (CLI_CLI_STR_EQUAL("half-duplex", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_HALF_DUPLEX, value);
    }
    else if (CLI_CLI_STR_EQUAL("priority-tag", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PRIORITY_TAG_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("station-move-action", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_STATION_MOVE_ACTION, value);
    }
    else if (CLI_CLI_STR_EQUAL("dscp-mode", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_DSCP_SELECT_MODE, value);
    }
    else if (CLI_CLI_STR_EQUAL("auto-neg", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_AUTO_NEG_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("auto-neg-mode", 1))
    {
        if (CLI_CLI_STR_EQUAL("1000base-X", 2))
        {
            value = CTC_PORT_AUTO_NEG_MODE_1000BASE_X;
        }
        else if (CLI_CLI_STR_EQUAL("sgmii-slaver", 2))
        {
            value = CTC_PORT_AUTO_NEG_MODE_SGMII_SLAVER;
        }
        else if (CLI_CLI_STR_EQUAL("sgmii-master", 2))
        {
            value = CTC_PORT_AUTO_NEG_MODE_SGMII_MASTER;
        }
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_AUTO_NEG_MODE, value);
    }
    else if (CLI_CLI_STR_EQUAL("qos-wrr", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_QOS_WRR_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("preamble", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PREAMBLE, value);
    }
    else if (CLI_CLI_STR_EQUAL("ipg-index", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_IPG, value);
    }
    else if (CLI_CLI_STR_EQUAL("unidirection", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_UNIDIR_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("link-intr", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_LINK_INTRRUPT_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("phy-init", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_INIT, value);
    }
    else if (CLI_CLI_STR_EQUAL("phy-en", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_EN, value);
    }
    else if (CLI_CLI_STR_EQUAL("phy-duplex", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_DUPLEX, value);
    } 
    else if (CLI_CLI_STR_EQUAL("phy-medium", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_MEDIUM, value);
    } 
    else if (CLI_CLI_STR_EQUAL("phy-loopback", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_LOOPBACK, value);
    } 
    else if (CLI_CLI_STR_EQUAL("phy-auto-neg", 1))
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_AUTO_NEG_EN, value);
    } 
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_port_show_port_property,
        ctc_cli_asw_port_show_port_property_cmd,
        "show port GPHYPORT_ID property (replace-stag-cos | replace-ctag-cos | replace-dscp | default-pcp | \
        default-dei |qos-trust | check-crc| strip-crc| append-crc|max-frame-size | station-move-action |half-duplex|priority-tag |dscp-mode | \
        default-dscp|replace-pcp-dei|qos-wrr|link-up|preamble|ipg-index|unidirection|link-intr|phy-init|phy-en| phy-duplex | phy-medium |phy-loopback | phy-auto-neg)",
        CTC_CLI_SHOW_STR,
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Property",
        "The STAG COS field is replaced by the classified COS result",
        "The CTAG COS field is replaced by the classified COS result",
        "The Dscp field is replaced by the qos mapping result",
        "Default cos of vlan tag",
        "Default dei of vlan tag",
        "Qos trust policy",
        "Check CRC",
        "Strip CRC",
        "Append CRC",
        "Max frame size",
        "Station move action",
        "Half duplex",
        "Priroty tag on port recevice or drop",
        "Dscp select mode, refer to ctc_dscp_select_mode_t",
        "Default dscp",
        "Replace pcp dei",
        "Qos WRR mode",
        "External PHY link status",
        "Port preamble",
        "Ipg index",
        "Unidirection",
        "Pcs link change interrupt enable",
        "Phy init",
        "Phy enable",
        "Phy duplex",
        "Phy medium",
        "Phy loopback",
        "Phy auto neg")
{
    int32 ret = 0;
    uint16 gport;
    uint32 value = FALSE;
    char* str = NULL;
    uint8 index = 0xFF;
    CTC_CLI_GET_UINT16("gport", gport, argv[0]);
    index = CTC_CLI_GET_ARGC_INDEX("replace-stag-cos");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_STAG_COS, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Replace-stag-cos", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("replace-ctag-cos");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_CTAG_COS, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Replace-ctag-cos", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("replace-dscp");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_DSCP_EN, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Replace-dscp", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("default-pcp");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_PCP, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Default-pcp", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("default-dei");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_DEI, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Default-dei", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("qos-trust");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_QOS_POLICY, &value);

        switch (value)
        {
            case CTC_QOS_TRUST_PORT:
                str = "port";
                break;

            case CTC_QOS_TRUST_STAG_COS:
                str = "stag-cos";
                break;

            case CTC_QOS_TRUST_DSCP:
                str = "dscp";
                break;

            default:
                str = "unexpect!!!!!";
                break;
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %s\n", "Qos-trust", str);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("check-crc");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_CHK_CRC_EN, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Check CRC", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("strip-crc");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_STRIP_CRC_EN, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Strip CRC", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("append-crc");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_APPEND_CRC_EN, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "Append CRC", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("max-frame-size");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_MAX_FRAME_SIZE, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-45s:  %u\n", "Max frame size",value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("mac-en");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_MAC_EN, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  0x%04x\n", "MAC en", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("station-move-action");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_STATION_MOVE_ACTION, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  0x%04x\n", "Station move action", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("half-duplex");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_HALF_DUPLEX, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  0x%04x\n", "Half duplex", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("priority-tag");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PRIORITY_TAG_EN, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  0x%04x\n", "Priority tag", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("dscp-mode");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_DSCP_SELECT_MODE, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  0x%04x\n", "Dscp select mode", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("default-dscp");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_DSCP, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  0x%04x\n", "Default dscp", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("replace-pcp-dei");
    if (index != 0xFF)
    {
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_REPLACE_PCP_DEI, &value);
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  0x%04x\n", "Replace pcp dei", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("qos-wrr");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_QOS_WRR_EN, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "Qos-wrr", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("link-up");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_LINK_UP, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "Link-up", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("preamble");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PREAMBLE, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "Preamble", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("ipg-index");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_IPG, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "Preamble", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("unidirection");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_UNIDIR_EN, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "unidirection", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("link-intr");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_LINK_INTRRUPT_EN, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "Port link interrupt enable", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("phy-init");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_INIT, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "phy-init", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("phy-en");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_EN, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "phy-en", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("phy-duplex");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_DUPLEX, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "phy-duplex", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("phy-medium");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_MEDIUM, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "phy-medium", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("phy-loopback");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_LOOPBACK, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "phy-loopback", value);
       }
    }
    index = CTC_CLI_GET_ARGC_INDEX("phy-auto-neg");
    if(index != 0xFF)
    {
       ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_PHY_AUTO_NEG_EN, &value);
       if (ret >= 0)
       {
           ctc_cli_out("%-34s:  %u\n", "phy-auto-neg", value);
       }
    }
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_port_show_port_dir_property,
        ctc_cli_asw_port_show_port_dir_property_cmd,
        "show port GPHYPORT_ID dir-property (qos-domain | policer-valid ) \
        direction ( ingress | egress)",
        CTC_CLI_SHOW_STR,
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Property with direction",
        "Port qos domain",
        "Port policer valid",
        "Direction",
        "Ingress",
        "Egress")
{
    int32 ret = 0;
    uint16 gport;
    uint32 value;
    ctc_direction_t dir = 0;
    uint8 index = 0xFF;
    CTC_CLI_GET_UINT16("gport", gport, argv[0]);
    ctc_cli_out("==============================\n");
    if CLI_CLI_STR_EQUAL("in", 2)
    {
        dir = CTC_INGRESS;
        ctc_cli_out("Ingress:\n");
    }
    else if CLI_CLI_STR_EQUAL("eg", 2)
    {
        dir = CTC_EGRESS;
        ctc_cli_out("Egress:\n");
    }
    index = CTC_CLI_GET_ARGC_INDEX("qos-domain");
    if (INDEX_VALID(index))
    {
        ret = ctcs_port_get_direction_property(g_api_lchip, gport, CTC_PORT_DIR_PROP_QOS_DOMAIN, dir, &value);
        if (ret >= 0)
        {
            ctc_cli_out("Qos-domain         :  %d\n", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("policer-valid");
    if (INDEX_VALID(index))
    {
        ret = ctcs_port_get_direction_property(g_api_lchip, gport, CTC_PORT_DIR_PROP_PORT_POLICER_VALID, dir, &value);
        if (ret >= 0)
        {
            ctc_cli_out("Policer-valid      :  %d\n", value);
        }
    }
    ctc_cli_out("==============================\n");
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_scl_property,
        ctc_cli_asw_port_set_scl_property_cmd,
        "port GPHYPORT_ID scl-key-type scl-id SCL_ID direction (ingress | egress) " \
        "type (cvid | svid  | dvid | mac-sa | ipsg-port-ip |ipv6 | ipv4 |svid-scos|cvid-ccos| disable) "\
        "(hash-vlan-range-disable |) " \
        "(tcam-type (mac | disable) |) ",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "SCL key type on port",
        "SCL id",
        "SCLID 0~1",
        "Direction",
        "Ingress",
        "Egress",
        "Hash Type",
        "Hash port cvlan",
        "Hash port svlan",
        "Hash port svlan cvlan",
        "Hash macsa",
        "Hash port ip sa",
        "Hash ipv6 sa",
        "Hash ipv4 sa",
        "Hash port svlan cos",
        "Hash port cvlan cos",
        "Hash disable",
        "Hash vlan range disable",
        "Tcam Type",
        "Tcam mac, layer2 tcam key",
        "Tcam disable")
{
    int32 ret = CLI_SUCCESS;
    uint16 gport = 0;
    uint8 index = 0xFF;
    ctc_port_scl_property_t port_scl_property;
    sal_memset(&port_scl_property, 0, sizeof(ctc_port_scl_property_t));

    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);
    CTC_CLI_GET_UINT8_RANGE("scl id", port_scl_property.scl_id, argv[1], 0, CTC_MAX_UINT8_VALUE);

    index = 3; /* hash type*/
    if (CLI_CLI_STR_EQUAL("ingress", 2))
    {
        port_scl_property.direction = CTC_INGRESS;

        if (CLI_CLI_STR_EQUAL("dvid", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_PORT_2VLAN;
        }
        else if (CLI_CLI_STR_EQUAL("svid-scos", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_PORT_SVLAN_COS;
        }
        else if (CLI_CLI_STR_EQUAL("cvid-ccos", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_PORT_CVLAN_COS;
        }
        else if (CLI_CLI_STR_EQUAL("svid", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_PORT_SVLAN;
        }
        else if (CLI_CLI_STR_EQUAL("cvid", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_PORT_CVLAN;
        }
        else if (CLI_CLI_STR_EQUAL("mac-sa", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_MAC_SA;
        }
        else if (CLI_CLI_STR_EQUAL("ipsg-port-ip", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_PORT_IP_SA;
        }
	    else if (CLI_CLI_STR_EQUAL("ipv6", index) || CLI_CLI_STR_EQUAL("ipv4", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_IP_SA;
        }
        else if (CLI_CLI_STR_EQUAL("disable", index))
        {
            port_scl_property.hash_type = CTC_PORT_IGS_SCL_HASH_TYPE_DISABLE;
        }
    }
    else
    {
        return CLI_ERROR;
    }

    index = CTC_CLI_GET_ARGC_INDEX("hash-vlan-range-disable");
    if (INDEX_VALID(index))
    {
        port_scl_property.hash_vlan_range_dis = 1;
    }
    index = CTC_CLI_GET_ARGC_INDEX("tcam-type");
    if (INDEX_VALID(index))
    {
        index ++;
        if (CLI_CLI_STR_EQUAL("mac", index))
        {
            port_scl_property.tcam_type = CTC_PORT_IGS_SCL_TCAM_TYPE_MAC;
        }
        else if (CLI_CLI_STR_EQUAL("disable", index))
        {
            port_scl_property.tcam_type = CTC_PORT_IGS_SCL_TCAM_TYPE_DISABLE;
        }
    }

    ret = ctcs_port_set_scl_property(g_api_lchip, gport, &port_scl_property);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_vlan_range,
        ctc_cli_asw_port_set_vlan_range_cmd,
        "port GPHYPORT_ID vlan-range direction (ingress|egress) {vrange-grp VRANGE_GROUP_ID |} (enable|disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Vlan range on port",
        "Direction",
        "Ingress",
        "Egress",
        "Vlan range group id",
        "<0-63>",
        "Enable vlan range",
        "Disable vlan range")
{
    int32 ret = CLI_SUCCESS;
    uint16 gport = 0;
    bool enable = FALSE;
    uint8  index = 0;
    ctc_vlan_range_info_t vrange_info;

    sal_memset(&vrange_info, 0, sizeof(ctc_vlan_range_info_t));
    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);


   if (CLI_CLI_STR_EQUAL("egress", 1))
    {
        return CLI_ERROR;
    }

    index = CTC_CLI_GET_ARGC_INDEX("vrange-grp");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8("vlan range group id", vrange_info.vrange_grpid, argv[index + 1]);
    }

    if (0xFF != CTC_CLI_GET_ARGC_INDEX("enable"))
    {
        enable = TRUE;
    }
    else if (0xFF != CTC_CLI_GET_ARGC_INDEX("disable"))
    {
        enable = FALSE;
    }

    ret = ctcs_port_set_vlan_range(g_api_lchip, gport, &vrange_info, enable);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_mac_en,
        ctc_cli_asw_port_set_mac_en_cmd,
        "port GPHYPORT_ID mac (enable | disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Port mac",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint16 gport;
    bool enable;

    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);

    if (CLI_CLI_STR_EQUAL("enable", 1))
    {
        enable = TRUE;
    }
    else
    {
        enable = FALSE;
    }

    ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_MAC_EN, enable);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_interface_mode,
        ctc_cli_asw_port_set_interface_mode_cmd,
        "port GPHYPORT_ID if-mode (10M|100M|1G|10G)\
            (100BASE-FX|SGMII|QSGMII)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Port interface mode",
        "10M speed",
        "100M speed",
        "1G speed",
        "10G speed",
        "100BASE FX type",
        "SGMII type",
        "QSGMII type")
{
    int32 ret = CLI_SUCCESS;
    uint32 gport;
    ctc_port_speed_t speed = 0;
    ctc_port_if_type_t interface_type = 0;
    ctc_port_if_mode_t if_mode;

    CTC_CLI_GET_UINT32_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT32_VALUE);

    if (CLI_CLI_STR_EQUAL("10M", 1))
    {
        speed = CTC_PORT_SPEED_100M;
    }
    else if (CLI_CLI_STR_EQUAL("100M", 1))
    {
        speed = CTC_PORT_SPEED_100M;
    }
    else if (CLI_CLI_STR_EQUAL("1G", 1))
    {
        speed = CTC_PORT_SPEED_1G;
    }
    else
    {
        ctc_cli_out("%% Not supported speed mode \n");
        return CTC_E_INVALID_PARAM;
    }

    if (CLI_CLI_STR_EQUAL("100BASE-FX", 2))
    {
        interface_type = CTC_PORT_IF_FX;
    }
    else if (CLI_CLI_STR_EQUAL("SGMII", 2))
    {
        interface_type = CTC_PORT_IF_SGMII;
    }
    else if (CLI_CLI_STR_EQUAL("QSGMII", 2))
    {
        interface_type = CTC_PORT_IF_QSGMII;
    }
    else
    {
        ctc_cli_out("%% Not supported interface type \n");
        return CTC_E_INVALID_PARAM;
    }

    if_mode.speed = speed;
    if_mode.interface_type = interface_type;

    ret = ctcs_port_set_interface_mode(g_api_lchip, gport, &if_mode);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_flow_ctl,
        ctc_cli_asw_port_set_flow_ctl_cmd,
        "port GPHYPORT_ID flow-ctl (ingress|egress|both)(enable|disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Flow control",
        "Receive pause frame",
        "Transmit pause frame",
        "Both receive and transmit",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = CLI_SUCCESS;
    uint8 index;
    uint16 gport = 0;
    ctc_direction_t dir = 0;
    uint8 enable = 0;
    ctc_port_fc_prop_t fc;

    sal_memset(&fc, 0, sizeof(fc));

    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);

    index = CTC_CLI_GET_ARGC_INDEX("ingress");
    if (0xFF != index)
    {
        dir = CTC_INGRESS;
    }

    index = CTC_CLI_GET_ARGC_INDEX("egress");
    if (0xFF != index)
    {
        dir = CTC_EGRESS;
    }

    index = CTC_CLI_GET_ARGC_INDEX("both");
    if (0xFF != index)
    {
        dir = CTC_BOTH_DIRECTION;
    }

    index = CTC_CLI_GET_ARGC_INDEX("enable");
    if (0xFF != index)
    {
       enable = 1;
    }
    fc.gport  = gport;
    fc.enable = enable;
    fc.dir    = dir;
    ret = ctcs_port_set_flow_ctl_en(g_api_lchip, &fc);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_default_vlan,
        ctc_cli_asw_port_set_default_vlan_cmd,
        "port GPHYPORT_ID default vlan VLAN_ID",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Default vlan tag",
        CTC_CLI_VLAN_DESC,
        CTC_CLI_VLAN_RANGE_DESC)
{
    int32 ret = 0;
    uint16 vlan_id = 0;
    uint16 gport = 0;

    CTC_CLI_GET_UINT16("gport", gport, argv[0]);
    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[1]);
    ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_DEFAULT_VLAN, vlan_id);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_vlan_ctl,
        ctc_cli_asw_port_set_vlan_ctl_cmd,
        "port GPHYPORT_ID vlan-ctl (allow-all | drop-all-untagged | drop-all-tagged | drop-all )",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Vlan control",
        "Allow all packet",
        "Drop all untagged packet",
        "Drop all tagged packet",
        "Drop all packet")
{
    int32 ret = 0;
    uint16 gport = 0;
    ctc_vlantag_ctl_t mode = 0;

    CTC_CLI_GET_UINT16("gport", gport, argv[0]);

    if (0 == sal_strcmp("allow-all", argv[1]))
    {
        mode = CTC_VLANCTL_ALLOW_ALL_PACKETS;
    }
    else if (0 == sal_strcmp("drop-all-untagged", argv[1]))
    {
        mode = CTC_VLANCTL_DROP_ALL_UNTAGGED;
    }
    else if (0 == sal_strcmp("drop-all-tagged", argv[1]))
    {
        mode = CTC_VLANCTL_DROP_ALL_TAGGED;
    }
    else if (0 == sal_strcmp("drop-all", argv[1]))
    {
        mode = CTC_VLANCTL_DROP_ALL;
    }
    else
    {
        mode = CTC_VLANCTL_ALLOW_ALL_PACKETS;
    }

    ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_VLAN_CTL, mode);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_show_flow_ctl,
        ctc_cli_asw_port_show_flow_ctl_cmd,
        "show port GPHYPORT_ID flow-ctl (ingress|egress)",
        CTC_CLI_SHOW_STR,
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Flow control",
        "Receive pause frame",
        "Transmit pause frame")
{
    int32 ret = CLI_SUCCESS;
    uint16 gport = 0;
    ctc_port_fc_prop_t fc;
    char* desc[2] = {"Ingress", "Egress"};
    uint8 index;
    ctc_direction_t dir = 0;

    sal_memset(&fc, 0, sizeof(fc));
    CTC_CLI_GET_UINT16("gport", gport, argv[0]);

    index = CTC_CLI_GET_ARGC_INDEX("ingress");
    if (0xFF != index)
    {
        dir = CTC_INGRESS;
    }

    index = CTC_CLI_GET_ARGC_INDEX("egress");
    if (0xFF != index)
    {
        dir = CTC_EGRESS;
    }

    fc.gport  = gport;
    fc.dir    = dir;

    ret = ctcs_port_get_flow_ctl_en(g_api_lchip, &fc);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    ctc_cli_out("==============================\n");

    ctc_cli_out("%-12s:\n", desc[fc.dir]);
    ctc_cli_out("enable      :  %d\n", fc.enable);

    ctc_cli_out("==============================\n");
    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_vlan_filtering,
        ctc_cli_asw_port_set_vlan_filtering_cmd,
        "port GPHYPORT_ID vlan-filtering direction (ingress | egress | both)(enable | disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Vlan filtering",
        "Filtering direction",
        "Ingress filtering",
        "Egress filtering",
        "Both igs and egs filtering",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint16 gport = 0;
    uint32 value = 0;
    ctc_direction_t dir = 0;

    CTC_CLI_GET_UINT16("gport", gport, argv[0]);
    if (0 == sal_memcmp("in", argv[1], 2))
    {
        dir = CTC_INGRESS;
    }
    else if (0 == sal_memcmp("eg", argv[1], 2))
    {
        dir = CTC_EGRESS;
    }
    else if (0 == sal_memcmp("bo", argv[1], 2))
    {
        dir = CTC_BOTH_DIRECTION;
    }
    if (0 == sal_memcmp("en", argv[2], 2))
    {
        value = 1;
    }
    else if (0 == sal_memcmp("disable", argv[2], 2))
    {
        value = 0;
    }
    ret = ctcs_port_set_direction_property(g_api_lchip, gport, CTC_PORT_DIR_PROP_VLAN_FILTER_EN, dir, value);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_acl_property,
        ctc_cli_asw_port_set_acl_property_cmd,
        "port GPHYPORT_ID acl-property priority PRIORITY_ID direction (ingress | egress ) acl-en (disable | (enable "\
        "tcam-lkup-type (mac | mac-ext | ipv4 | mac-ipv4 | ipv4-ext |mac-ipv6 | ipv6 |"\
        "ipv6-ext | udf ) (use-l4-port-range (use-cvlan-range |)| ) ) )",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Acl property on port",
        "Acl priority",
        "PRIORITY_ID",
        "direction",
        "ingress",
        "egress",
        "Port acl en",
        "Disable function",
        "Enable function",
        "Tcam lookup type",
        "Mac key",
        "Mac extend key",
        "Ipv4 key",
        "Mac-ipv4 key",
        "Ipv4 extend key",
        "Mac ipv6 key",
        "Ipv6  key",
        "Ipv6 extend key",
        "Udf key",
        "Use l4 port range",
        "Use cvlan range as vlan range")
{
    int32 ret = CLI_SUCCESS;
    uint16 gport = 0;
    uint8 index = 0;
    ctc_acl_property_t prop;

    /*default is use port_bitmap*/
    sal_memset(&prop,0,sizeof(ctc_acl_property_t));

    CTC_CLI_GET_UINT16("port", gport, argv[0] );
    CTC_CLI_GET_UINT8("priority",prop.acl_priority,argv[1] );

    if(CLI_CLI_STR_EQUAL("disable",3))
    {
        prop.acl_en = 0;
    }
    else
    {
        prop.acl_en = 1;
    }

    index = CTC_CLI_GET_ARGC_INDEX("tcam-lkup-type");
    if(0xFF != index)
    {
        if(CTC_CLI_STR_EQUAL_ENHANCE("mac-ext",index + 1))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_MAC_EXT;
        }
	    else  if(CTC_CLI_STR_EQUAL_ENHANCE("mac",index + 1))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_MAC;
        }
        else if(CTC_CLI_STR_EQUAL_ENHANCE("ipv4-ext", index + 1))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_IPV4_EXT;
        }
        else if(CLI_CLI_STR_EQUAL("mac-ipv4",index + 1))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_MAC_IPV4;
        }
        else if(CTC_CLI_STR_EQUAL_ENHANCE("mac-ipv6",index + 1 ))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_MAC_IPV6;
        }
        else if(CTC_CLI_STR_EQUAL_ENHANCE("ipv4", index + 1))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_IPV4;
        }
	    else if(CLI_CLI_STR_EQUAL("ipv6-ext",index + 1 ))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_IPV6_EXT;
        }
        else if(CLI_CLI_STR_EQUAL("ipv6",index + 1 ))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_IPV6;
        }
        else if(CTC_CLI_STR_EQUAL_ENHANCE("udf",index + 1 ))
        {
            prop.tcam_lkup_type = CTC_ACL_KEY_UDF;
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("use-l4-port-range");
    if (0xFF != index)
    {
        prop.flag |= CTC_ACL_PROP_FLAG_USE_L4_PORT_RANGE;
        if(0xff != CTC_CLI_GET_ARGC_INDEX("use-cvlan-range"))
        {
            prop.flag |= CTC_ACL_PROP_FLAG_USE_CVLAN_RANGE;
        }
    }
    ret = ctcs_port_set_acl_property(g_api_lchip, gport, &prop);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_show_acl_property,
        ctc_cli_asw_port_show_acl_property_cmd,
        "show port GPHYPORT_ID acl-property direction (ingress | egress) (detail | )",
        CTC_CLI_SHOW_STR,
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Port acl property",
        "Direction",
        "Ingress",
        "Egress",
        "Detail")
{
    int32  ret = CLI_SUCCESS;
    uint16 gport = 0;
    uint8 index =0;
    ctc_acl_property_t prop;

    sal_memset(&prop, 0, sizeof(ctc_acl_property_t));

    CTC_CLI_GET_UINT16("port", gport, argv[0]);

    ctc_cli_out("==========================================================================================\n");

    index = CTC_CLI_GET_ARGC_INDEX("detail");
    if (0xFF != index)
    {
        ctc_cli_out("Prio    acl-en    tcam-lkup-type     l4-port-range(vRange) \n");
        prop.flag = 0;
        for (prop.acl_priority = 0; prop.acl_priority < 4; prop.acl_priority++)
        {
            ret = ctcs_port_get_acl_property(g_api_lchip, gport, &prop);
            if (ret < 0)
            {
                ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
                return CLI_ERROR;/*return CLI_ERROR; no error for compatiable*/
            }
            if (prop.acl_en)
            {
                char* vrange[3] = {"-", "cvid", "svid"};
                uint8 vrange_id = CTC_FLAG_ISSET(prop.flag, CTC_ACL_PROP_FLAG_USE_L4_PORT_RANGE) ? 
                    (CTC_FLAG_ISSET(prop.flag, CTC_ACL_PROP_FLAG_USE_CVLAN_RANGE) ? 1 : 2 ): 0;
                
                ctc_cli_out("%-6d   %-14s %-15u  %s(%4s)\n",  prop.acl_priority, "YES",prop.tcam_lkup_type,
                            CTC_FLAG_ISSET(prop.flag, CTC_ACL_PROP_FLAG_USE_L4_PORT_RANGE) ? "YES" : "NO", vrange[vrange_id]);
            }
            else
            {
                ctc_cli_out("%-9s %-15s %-15s%-15s\n", "-", "-", "-", "-");
            }
        }
    }
    else
    {
        ctc_cli_out(" acl-en    tcam-lkup-type     l4-port-range(vRange) \n");
        prop.flag = 0;
        ret = ctcs_port_get_acl_property(g_api_lchip, gport, &prop);
        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
            return CLI_ERROR;/*return CLI_ERROR; no error for compatiable*/
        }
        if (prop.acl_en)
        {
            char* vrange[3] = {"-", "cvid", "svid"};
            uint8 vrange_id = CTC_FLAG_ISSET(prop.flag, CTC_ACL_PROP_FLAG_USE_L4_PORT_RANGE) ? 
                (CTC_FLAG_ISSET(prop.flag, CTC_ACL_PROP_FLAG_USE_CVLAN_RANGE) ? 1 : 2 ): 0;
            
            ctc_cli_out("   %-14s %-15u  %s(%4s)\n", "YES", prop.tcam_lkup_type,
                        CTC_FLAG_ISSET(prop.flag, CTC_ACL_PROP_FLAG_USE_L4_PORT_RANGE) ? "YES" : "NO", vrange[vrange_id]);
        }
        else
        {
            ctc_cli_out("  %-15s %-15s%-15s\n", "-", "-", "-");
        }
    }

    ctc_cli_out("==========================================================================================\n");
    return ret;
}


CTC_CLI(ctc_cli_asw_port_set_vlan_domain,
        ctc_cli_asw_port_set_vlan_domain_cmd,
        "port GPHYPORT_ID vlan-domain (cvlan | svlan)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Set vlan domain when the cvlan TPID is the same as svlan TPID",
        "Cvlan domain",
        "Svlan domain")
{
    int32 ret = 0;
    uint16 gport = 0;
    ctc_port_vlan_domain_type_t vlan_domain = CTC_PORT_VLAN_DOMAIN_SVLAN;

    CTC_CLI_GET_UINT16("gport", gport, argv[0]);

    if (0 == sal_memcmp("cvlan", argv[1], 5))
    {
        vlan_domain = CTC_PORT_VLAN_DOMAIN_CVLAN;
    }

    ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_VLAN_DOMAIN, vlan_domain);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}
CTC_CLI(ctc_cli_asw_port_show_port_maclink,
        ctc_cli_asw_port_show_port_maclink_cmd,
        "show port mac-link ",
        CTC_CLI_SHOW_STR,
        CTC_CLI_PORT_M_STR,
        "Port mac link status")
{
    int32 ret = CLI_SUCCESS;
    uint16 gport_idx = 0;
    uint32 gport = 0;
    uint32 value_mac_en = FALSE;
    uint32 value_link_up = FALSE;
    uint32 value_32 = 0;
    char value_c[29] = {0};

    ctc_cli_out(" Show Local Port Link:\n");
    ctc_cli_out(" ----------------------------------------------------------------------------------  \n");
    ctc_cli_out(" %-8s%-7s%-9s%-7s%-8s%-8s\n","GPort", "Link", "MAC-EN", "Speed", "Duplex", "Auto-Neg");
    ctc_cli_out(" ------------------------------------------------------------------------------------\n");
    for (gport_idx = 0; gport_idx < CTC_ASW_MAX_PHY_PORT; gport_idx++)
    {
        gport = gport_idx;
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_LINK_UP, &value_link_up);
        if (ret < 0)
        {
            continue;
        }
        ctc_cli_out(" 0x%04X%-4s", gport, "");
        if (value_link_up)
        {
            ctc_cli_out("%-7s", "up");
        }
        else
        {
            ctc_cli_out("%-7s", "down");
        }
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_MAC_EN, &value_mac_en);
        if (ret < 0)
        {
            continue;
        }
        ctc_cli_out("%-9s", (value_mac_en ? "TRUE":"FALSE"));
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_SPEED, (uint32*)&value_32);
        if (ret < 0)
        {
            ctc_cli_out("%-7s", "-");
        }
        else
        {
            sal_memset(value_c, 0, sizeof(value_c));
            if (CTC_PORT_SPEED_1G == value_32)
            {
                sal_memcpy(value_c, "1G", sal_strlen("1G"));
            }
            else if (CTC_PORT_SPEED_100M == value_32)
            {
                sal_memcpy(value_c, "100M", sal_strlen("100M"));
            }
            else if (CTC_PORT_SPEED_10M == value_32)
            {
                sal_memcpy(value_c, "10M", sal_strlen("10M"));
            }
            ctc_cli_out("%-7s", value_c);
        }
        ctc_cli_out("%-8s", "FD");
        ret = ctcs_port_get_property(g_api_lchip, gport, CTC_PORT_PROP_AUTO_NEG_EN, &value_32);
        if (ret < 0)
        {
            ctc_cli_out("%-7s", "-");
        }
        else
        {
            ctc_cli_out("%-10s", (value_32 ? "TRUE" : "FALSE"));
        }
        ctc_cli_out("\n");
    }
    ctc_cli_out(" ------------------------------------------------------------------------------------ \n");
    ctc_cli_out(" \n");
    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_port_set_speed,
        ctc_cli_asw_port_set_speed_cmd,
        "port GPHYPORT_ID speed-mode (eth|fe|ge)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Port speed mode",
        "Ethernet port with 10M",
        "Fast Eth port with 100M",
        "GEth port with 1G")
{
    int32 ret = CLI_SUCCESS;
    uint32 gport;
    ctc_port_speed_t speed_mode = 0;

    CTC_CLI_GET_UINT32_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT32_VALUE);

    if (CLI_CLI_STR_EQUAL("eth", 1))
    {
        speed_mode = CTC_PORT_SPEED_10M;
    }
    else if (CLI_CLI_STR_EQUAL("fe", 1))
    {
        speed_mode = CTC_PORT_SPEED_100M;
    }
    else if (CLI_CLI_STR_EQUAL("ge", 1))
    {
        speed_mode = CTC_PORT_SPEED_1G;
    }

    ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_SPEED, speed_mode);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_port_set_all_mac_en,
        ctc_cli_asw_port_set_all_mac_en_cmd,
        "port all mac (enable | disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Port mac",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint16 gport;
    bool enable;

    if (CLI_CLI_STR_EQUAL("enable", 0))
    {
        enable = TRUE;
    }
    else
    {
        enable = FALSE;
    }
    for (gport = 0; gport < CTC_ASW_MAX_PHY_PORT; gport++)
    {
        ret = ctcs_port_set_property(g_api_lchip, gport, CTC_PORT_PROP_MAC_EN, enable);
        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
            return CLI_ERROR;
        }
    }

    return ret;
}


CTC_CLI(ctc_cli_asw_port_set_blocking,
        ctc_cli_asw_port_set_blocking_cmd,
        "port GPHYPORT_ID port-blocking {ucast-flooding | mcast-flooding | bcast-flooding} \
        (enable|disable)",
        CTC_CLI_PORT_M_STR,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Port based blocking",
        "Unknown ucast flooding to this port",
        "Unknown mcast flooding to this port",
        "Broadcast flooding to this port",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint32 gport = 0;
    uint8 index = 0;
    ctc_port_restriction_t port_restriction;

    sal_memset(&port_restriction, 0, sizeof(ctc_port_restriction_t));

    CTC_CLI_GET_UINT32_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT32_VALUE);
    index = CTC_CLI_GET_ARGC_INDEX("disable");
    if (index != 0xFF)
    {
        port_restriction.mode = CTC_PORT_RESTRICTION_DISABLE;
        index = CTC_CLI_GET_ARGC_INDEX("ucast-flooding");
        if (index != 0xFF)
        {
            CTC_UNSET_FLAG(port_restriction.type, CTC_PORT_BLOCKING_UNKNOW_UCAST);
        }

        index = CTC_CLI_GET_ARGC_INDEX("mcast-flooding");
        if (index != 0xFF)
        {
            CTC_UNSET_FLAG(port_restriction.type, CTC_PORT_BLOCKING_UNKNOW_MCAST);
        }

        index = CTC_CLI_GET_ARGC_INDEX("bcast-flooding");
        if (index != 0xFF)
        {
            CTC_UNSET_FLAG(port_restriction.type, CTC_PORT_BLOCKING_BCAST);
        }
    }
    else
    {
        port_restriction.mode = CTC_PORT_RESTRICTION_PORT_BLOCKING;

        index = CTC_CLI_GET_ARGC_INDEX("ucast-flooding");
        if (index != 0xFF)
        {
            CTC_SET_FLAG(port_restriction.type, CTC_PORT_BLOCKING_UNKNOW_UCAST);
        }

        index = CTC_CLI_GET_ARGC_INDEX("mcast-flooding");
        if (index != 0xFF)
        {
            CTC_SET_FLAG(port_restriction.type, CTC_PORT_BLOCKING_UNKNOW_MCAST);
        }

        index = CTC_CLI_GET_ARGC_INDEX("bcast-flooding");
        if (index != 0xFF)
        {
            CTC_SET_FLAG(port_restriction.type, CTC_PORT_BLOCKING_BCAST);
        }
    }

    ret = ctcs_port_set_restriction(g_api_lchip, gport, &port_restriction);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

int32
ctc_asw_port_cli_init(uint8 cli_tree_mode)
{
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_stag_tpid_index_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_port_isolation_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_show_port_isolation_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_learning_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_show_port_info_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_dir_property_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_property_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_show_port_property_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_show_port_dir_property_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_scl_property_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_vlan_range_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_mac_en_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_interface_mode_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_flow_ctl_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_show_flow_ctl_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_default_vlan_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_vlan_ctl_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_vlan_filtering_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_acl_property_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_show_acl_property_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_newsa_drop_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_vlan_domain_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_show_port_maclink_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_speed_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_all_mac_en_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_port_set_blocking_cmd);
    return 0;
}



